package com.axs.camera;

import static com.axs.camera.remote.RetrofitManager.TOKEN;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import com.axs.camera.bean.PhotoResultBean;
import com.axs.camera.crop.util.LoadingDailogs;
import com.axs.camera.crop.util.SelfDialog3;
import com.axs.camera.remote.ApiService;
import com.axs.camera.remote.RetrofitManager;
import com.google.gson.Gson;
import com.jeremyliao.liveeventbus.LiveEventBus;
import com.newland.springdialog.AnimSpring;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Calendar;
import java.util.Locale;

import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;

public class MainActivity2 extends AppCompatActivity implements View.OnClickListener {

    public static final int CHOOSE_PHOTO = 2;
    public static final String KEY_IMAGE_PATH = "imagePath";
    /**
     * 相机预览
     */
    private FrameLayout mPreviewLayout;
    /**
     * 拍摄按钮视图
     */
    private RelativeLayout mPhotoLayout;

    /**
     * 顶部视图
     */
    private RelativeLayout upLayout;


    /**
     * 闪光灯
     */
    private ImageView mFlashButton;
    /**
     * 拍照按钮
     */
    private ImageView mPhotoButton;
    /**
     * 聚焦视图
     */
    private OverCameraView mOverCameraView;
    /**
     * 相机类
     */
    private Camera mCamera;
    /**
     * Handle
     */
    private Handler mHandler = new Handler();
    private Runnable mRunnable;
    /**
     * 取消按钮
     */
    private ImageView mCancleButton;
    /**
     * 是否开启闪光灯
     */
    private boolean isFlashing;
    /**
     * 图片流暂存
     */
    private byte[] imageData;
    /**
     * 拍照标记
     */
    private boolean isTakePhoto;
    /**
     * 是否正在聚焦
     */
    private boolean isFoucing;

    /**
     * 图库按钮
     */
    private TextView gallery;

    private SelfDialog3 dialog;
    private String message;
    private ApiService apiService = RetrofitManager.getInstance().getRetrofit().create(ApiService.class);
    private LoadingDailogs loadingDailogs;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();
        setOnclickListener();
    }


    /**
     * 注释：初始化视图
     */
    private void initView() {
        mCancleButton = findViewById(R.id.cancle_button);
        mPreviewLayout = findViewById(R.id.camera_preview_layout);
        mPhotoLayout = findViewById(R.id.ll_photo_layout);
        mPhotoButton = findViewById(R.id.take_photo_button);
        mFlashButton = findViewById(R.id.flash_button);
        gallery = findViewById(R.id.gallerys);
        upLayout = findViewById(R.id.up_layout);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
        CameraPreview preview = new CameraPreview(this, mCamera);
        mOverCameraView = new OverCameraView(this);
        mPreviewLayout.addView(preview);
        mPreviewLayout.addView(mOverCameraView);
    }


    /**
     * 注释：设置监听事件
     */
    private void setOnclickListener() {
        mCancleButton.setOnClickListener(this);
        mFlashButton.setOnClickListener(this);
        mPhotoButton.setOnClickListener(this);
        gallery.setOnClickListener(this);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            if (!isFoucing) {
                float x = event.getX();
                float y = event.getY();
                isFoucing = true;
                if (mCamera != null && !isTakePhoto) {
                    mOverCameraView.setTouchFoucusRect(mCamera, autoFocusCallback, x, y);
                }
                mRunnable = () -> {
                    Toast.makeText(MainActivity2.this, "自动聚焦超时,请调整合适的位置拍摄！", Toast.LENGTH_SHORT);
                    isFoucing = false;
                    mOverCameraView.setFoucuing(false);
                    mOverCameraView.disDrawTouchFocusRect();
                };
                //设置聚焦超时
                mHandler.postDelayed(mRunnable, 3000);
            }
        }
        return super.onTouchEvent(event);
    }

    /**
     * 注释：自动对焦回调
     */
    private Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            isFoucing = false;
            mOverCameraView.setFoucuing(false);
            mOverCameraView.disDrawTouchFocusRect();
            //停止聚焦超时回调
            mHandler.removeCallbacks(mRunnable);
        }
    };

    /**
     * 注释：拍照并保存图片到相册
     */
    private void takePhoto() {
        isTakePhoto = true;
        //调用相机拍照
        mCamera.takePicture(null, null, null, (data, camera1) -> {
            //视图动画
            upLayout.setVisibility(View.GONE);//关闭顶部视图
            mPhotoLayout.setVisibility(View.GONE);//底部拍照按钮
            imageData = data;
            //停止预览
            mCamera.stopPreview();
            //保存后进行裁剪
            savePhoto();
        });
    }

    /**
     * 注释：切换闪光灯
     */
    private void switchFlash() {
        isFlashing = !isFlashing;
        mFlashButton.setImageResource(isFlashing ? R.mipmap.flash_open : R.mipmap.flash_close);
        AnimSpring.getInstance(mFlashButton).startRotateAnim(120, 360);
        try {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setFlashMode(isFlashing ? Camera.Parameters.FLASH_MODE_TORCH : Camera.Parameters.FLASH_MODE_OFF);
            mCamera.setParameters(parameters);
        } catch (Exception e) {
            Toast.makeText(this, "该设备不支持闪光灯", Toast.LENGTH_SHORT);
        }
    }

    /**
     * 注释：取消保存
     */
    private void cancleSavePhoto() {
        upLayout.setVisibility(View.VISIBLE);
        mPhotoLayout.setVisibility(View.VISIBLE);
        AnimSpring.getInstance(mPhotoLayout).startRotateAnim(120, 360);
        //开始预览
        mCamera.startPreview();
        imageData = null;
        isTakePhoto = false;
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        System.out.println(id);
        if (id == R.id.cancle_button) {
            finish();
        } else if (id == R.id.take_photo_button) {
            if (!isTakePhoto) {
                takePhoto();
            }
        } else if (id == R.id.flash_button) {
            switchFlash();
        } else if (id == R.id.gallerys) {
            aa();
        }
    }

    /**
     * 注释：保存图片
     */
    private void savePhoto() {
        FileOutputStream fos = null;
        //获取路径
        String name = DateFormat.format("yyyyMMddhhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
        Log.d("TAG", "savePhoto: " + name);
        FileOutputStream outputStream = null;
        String printTxtPath = getExternalCacheDir().getAbsolutePath();//当前程序路径
        File file = new File(printTxtPath);
        if (!file.exists()) {
            file.mkdirs();// 创建文件夹
        }
        String imagePath = printTxtPath + "/" + name;
        File imageFile = new File(imagePath);
        try {
            fos = new FileOutputStream(imageFile);
            fos.write(imageData);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                    Bitmap retBitmap = BitmapFactory.decodeFile(imagePath);
                    retBitmap = BitmapUtils.setTakePicktrueOrientation(Camera.CameraInfo.CAMERA_FACING_BACK, retBitmap);
                    Log.d("TAG", "savePhotoretBitmap: " + retBitmap.getRowBytes()*retBitmap.getHeight());
                    try {
                        String base64 = BitmapUtils.bitmapToBase64(retBitmap);
                        String img = "image=" + base64 + "&baike_num=5";
                        String imgParam = URLEncoder.encode(img, "UTF-8");
                        RequestBody body = RequestBody.create(imgParam, MediaType.get("application/json"));
                        apiService.plantClassify(TOKEN, body)
                                .subscribeOn(Schedulers.io())
                                .observeOn(AndroidSchedulers.mainThread())
                                .subscribe(new Observer<PhotoResultBean>() {
                                    @Override
                                    public void onSubscribe(Disposable d) {
                                        showNetProgessDialog("正在识别...", false);
                                    }

                                    @Override
                                    public void onNext(PhotoResultBean photoResultBean) {
                                        if (!TextUtils.isEmpty(photoResultBean.getErrorMsg())) {
                                            imageFile.delete();
                                            Toast.makeText(MainActivity2.this, "尚未识别到植物，请重新识别！", Toast.LENGTH_SHORT).show();
                                            return;
                                        }
                                        if (photoResultBean.getResult() != null && photoResultBean.getResult().size() > 0) {
                                            PhotoResultBean.ResultDTO dto = photoResultBean.getResult().get(0);

                                            if (dto.getName().equals("非植物")) {
                                                imageFile.delete();
                                            } else {
                                                String newPath = imageFile.getPath();
                                                File newFile = new File(newPath.replace(".png", dto.getName() + ".png"));
                                                imageFile.renameTo(newFile);


                                                LiveEventBus.get("result", String.class)
                                                        .post(new Gson().toJson(photoResultBean.getResult()));
                                                startActivity(new Intent(MainActivity2.this, ResultActivity.class));
                                                finish();
                                            }
                                            //showDialog1(dto.getName());
                                        }
                                    }

                                    @Override
                                    public void onError(Throwable e) {
                                        loadDismiss();
                                    }

                                    @Override
                                    public void onComplete() {
                                        loadDismiss();
                                    }
                                });
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    setResult(RESULT_FIRST_USER);
                    e.printStackTrace();
                }
            }
            //在这里写放在list
            //showDialog1(message);
        }
    }

    private void showDialog1(String messsage) {
        dialog = new SelfDialog3(this, false);
        dialog.setTitle("植被信息");
        dialog.setMessage(messsage);

        dialog.setNoOnclickListener("取消", () -> dialog.dismiss());
        dialog.setYesOnclickListener("确定", () -> {
            dialog.dismiss();
            finish();
        });
        dialog.show();
    }


    /**
     * 图库
     */
    public void aa() {
        //动态申请读取SD卡权限
        if (ContextCompat.checkSelfPermission(MainActivity2.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity2.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
        } else {
            openAlbum();
        }
    }

    private void openAlbum() {
        Intent intent = new Intent("android.intent.action.GET_CONTENT");
        intent.setType("image/*");
        startActivityForResult(intent, CHOOSE_PHOTO); //打开相册
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    openAlbum();
                } else {
                    Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }

    //Overriding method should call super.onActivityResult
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        System.out.println("99999999999999999999999999999999999966666666666666");
        if (resultCode == RESULT_OK) {
            //判断手机系统版本号
            if (Build.VERSION.SDK_INT >= 19) {
                //4.4及以上系统使用这个方法处理图片
                handleImageOnKitKat(data);
            } else {
                handleImageBeforeKitKat(data);
            }
        }
    }

    public byte[] UriToByte(Uri uri) {
        Bitmap bitmap1 = null;
        try {
            bitmap1 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
        } catch (IOException e) {
            e.printStackTrace();
        }

        int size = bitmap1.getWidth() * bitmap1.getHeight() * 4;
        ByteArrayOutputStream baos = new ByteArrayOutputStream(size);
        bitmap1.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] imagedata1 = baos.toByteArray();

        return imagedata1;
    }

    @TargetApi(19)
    private void handleImageOnKitKat(Intent data) {
        String imagePath = null;
        Uri uri = data.getData();
        if (DocumentsContract.isDocumentUri(this, uri)) {
            /*如果是document类型的Uri，则通过document id处理*/
            String docId = DocumentsContract.getDocumentId(uri);
            if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
                String id = docId.split(":")[1]; //解析出数字格式的id
                String selection = MediaStore.Images.Media._ID + "=" + id;
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
            } else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
                imagePath = getImagePath(contentUri, null);
            }
        } else if ("content".equalsIgnoreCase(uri.getScheme())) {
            //如果是content类型的uri，则使用普通方式处理
            imagePath = getImagePath(uri, null);
        } else if ("file".equalsIgnoreCase(uri.getScheme())) {
            //如果是file类型的uri，直接获取图片路径即可
            imagePath = uri.getPath();
        }
        File imageFiles = new File(imagePath);
        //displayImage(imagePath); //根据图片路径显示图片
        Bitmap retBitmap = BitmapFactory.decodeFile(imagePath);
        retBitmap = BitmapUtils.setTakePicktrueOrientation(Camera.CameraInfo.CAMERA_FACING_BACK, retBitmap);
        Log.d("TAG", "handleImageOnKitKatimagePath: " + imagePath);
        try {
            String base64 = BitmapUtils.bitmapToBase64(retBitmap);
            String img = "image=" + base64 + "&baike_num=5";
            String imgParam = URLEncoder.encode(img, "UTF-8");
            RequestBody body = RequestBody.create(imgParam, MediaType.get("application/json"));
            apiService.plantClassify(TOKEN, body)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<PhotoResultBean>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            showNetProgessDialog("正在识别...", true);
                        }

                        @Override
                        public void onNext(PhotoResultBean photoResultBean) {
                            if (!TextUtils.isEmpty(photoResultBean.getErrorMsg())) {
                                imageFiles.delete();
                                Toast.makeText(MainActivity2.this, "尚未识别到植物，请重新识别！", Toast.LENGTH_SHORT).show();
                                return;
                            }
                            if (photoResultBean.getResult() != null && photoResultBean.getResult().size() > 0) {
                                PhotoResultBean.ResultDTO dto = photoResultBean.getResult().get(0);

                                if (dto.getName().equals("非植物")) {
                                    imageFiles.delete();
                                } else {
                                    String newPath = imageFiles.getPath();
                                    File newFile = new File(newPath.replace(".png", dto.getName() + ".png"));
                                    imageFiles.renameTo(newFile);


                                    LiveEventBus.get("result", String.class)
                                            .post(new Gson().toJson(photoResultBean.getResult()));
                                    startActivity(new Intent(MainActivity2.this, ResultActivity.class));
                                    finish();
                                }

                                //showDialog1(dto.getName());
                            }
                        }

                        @Override
                        public void onError(Throwable e) {
                            loadDismiss();
                        }

                        @Override
                        public void onComplete() {
                            loadDismiss();
                        }
                    });
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }

    private void handleImageBeforeKitKat(Intent data) {
        Uri uri = data.getData();
        String imagePath = getImagePath(uri, null);
        displayImage(imagePath);
        Log.d("TAG", "handleImageOnKitKat: " + imagePath);
    }

    private String getImagePath(Uri uri, String selection) {
        String path = null;
        //通过Uri和selection来获取真实的图片路径
        Cursor cursor = getContentResolver().query(uri, null, selection, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
            }
            cursor.close();
        }
        return path;
    }

    private void displayImage(String imagePath) {
        if (imagePath != null) {
        } else {
            Toast.makeText(this, "failed to get image", Toast.LENGTH_SHORT).show();
        }
    }

    //显示网络加载框
    public void showNetProgessDialog(String text, boolean isback) {
        if (loadingDailogs == null) {
            LoadingDailogs.Builder builder1 = new LoadingDailogs.Builder(this)
                    .setShowMessage(true)
                    .setMessage(text)
                    .setCancelable(isback);
            loadingDailogs = builder1.create();
            loadingDailogs.show();
        } else {
            loadingDailogs.show();
        }
    }

    /**
     * 让加载框中消失
     */
    public void loadDismiss() {
        if (loadingDailogs != null && loadingDailogs.isShowing()) {
            loadingDailogs.dismiss();
        }
    }
}